package com.itheima.weirpc.server.tcp;

import com.itheima.weirpc.protocol.ProtocolConstant;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.parsetools.RecordParser;



/**
 * ClassName: TcpBufferHandlerWrapper
 * Package: com.itheima.weirpc.server.tcp
 * Description:
 * TCP 消息处理器包装
 * 装饰者模式，使用recordParser 对原有的buffer 处理能力进行增强
 *
 * @Author 看到风
 * @Create 2024/12/12 19:44
 * @Version 1.0
 */

public class TcpBufferHandlerWrapper implements Handler<Buffer> {
    /**
     * 解析器，用于解决半包，粘包问题
     * @param buffer
     */
    private final RecordParser recordParser;

    public TcpBufferHandlerWrapper(Handler<Buffer> bufferHandler){
        recordParser = initRecordParser(bufferHandler);
    }
    @Override
    public void handle(Buffer buffer) {
        recordParser.handle(buffer);
    }

    /**
     * 初始化解析器
     * @param bufferHandler
     * @return
     */
    private RecordParser initRecordParser(Handler<Buffer> bufferHandler){
      //构造parser
      RecordParser parser = RecordParser.newFixed(ProtocolConstant.MESSAGE_HEADER_LENGTH);

      parser.setOutput(new Handler<Buffer>() {
          //初始化
          int size = -1;
          //一次完整的读书（头和体）
          Buffer resultBuffer = Buffer.buffer();
          @Override
          public void handle(Buffer buffer) {
        //1.每次循环，首先读取消息头
              if(-1==size){
                  //读取消息体长度
                  size = buffer.getInt(13);
                  parser.fixedSizeMode(size);
                  //写入头信息到结果
                  resultBuffer.appendBuffer(buffer);
              }else {
                  //2.然后读取消息体
                  //写入体信息到结果
                  resultBuffer.appendBuffer(buffer);
                  //已拼接为完整Buffer,执行处理
                  bufferHandler.handle(resultBuffer);
                  //重置一轮
                  parser.fixedSizeMode(ProtocolConstant.MESSAGE_HEADER_LENGTH);
                  size = -1;
                  resultBuffer = Buffer.buffer();
              }

          }
      });
      return  parser;
    }
}
